{\rtf1\ansi\ansicpg1252\cocoartf2512
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;\f1\fnil\fcharset0 Menlo-Bold;}
{\colortbl;\red255\green255\blue255;\red93\green108\blue121;\red255\green255\blue255;\red0\green0\blue0;
\red155\green35\blue147;\red11\green79\blue121;\red57\green0\blue160;\red15\green104\blue160;\red28\green70\blue74;
\red196\green26\blue22;\red28\green0\blue207;\red108\green54\blue169;\red50\green109\blue116;\red100\green56\blue32;
}
{\*\expandedcolortbl;;\csgenericrgb\c36526\c42188\c47515;\csgenericrgb\c100000\c100000\c100000;\csgenericrgb\c0\c0\c0\c85000;
\csgenericrgb\c60759\c13753\c57628;\csgenericrgb\c4314\c30980\c47451;\csgenericrgb\c22454\c0\c62803;\csgenericrgb\c5882\c40784\c62745;\csgenericrgb\c10981\c27276\c28869;
\csgenericrgb\c77000\c10200\c8600;\csgenericrgb\c11000\c0\c81000;\csgenericrgb\c42190\c21278\c66379;\csgenericrgb\c19418\c42935\c45455;\csgenericrgb\c39147\c22031\c12446;
}
\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\deftab593
\pard\tx593\pardeftab593\pardirnatural\partightenfactor0

\f0\fs24 \cf2 \cb3 //\cf4 \
\cf2 //  ModelParser.swift\cf4 \
\cf2 //  firstlite\cf4 \
\cf2 //\cf4 \
\cf2 //  Created by Laurence on 5/6/20.\cf4 \
\cf2 //  Copyright \'a9 2020 lmoroney. All rights reserved.\cf4 \
\cf2 //\cf4 \
\

\f1\b \cf5 import
\f0\b0 \cf4  Foundation\

\f1\b \cf5 import
\f0\b0 \cf4  TensorFlowLite\
\

\f1\b \cf5 typealias
\f0\b0 \cf4  \cf6 FileInfo\cf4  = (name: \cf7 String\cf4 , extension: \cf7 String\cf4 )\
\

\f1\b \cf5 enum
\f0\b0 \cf4  \cf6 ModelFile\cf4  \{\
  
\f1\b \cf5 static
\f0\b0 \cf4  
\f1\b \cf5 let
\f0\b0 \cf4  \cf8 modelInfo\cf4 : \cf9 FileInfo\cf4  = (name: \cf10 "model"\cf4 , extension: \cf10 "tflite"\cf4 )\
\}\
\

\f1\b \cf5 class
\f0\b0 \cf4  \cf6 ModelParser\cf4  \{\
  \
  
\f1\b \cf5 private
\f0\b0 \cf4  
\f1\b \cf5 var
\f0\b0 \cf4  \cf8 interpreter\cf4 : \cf9 Interpreter\cf4 \
  
\f1\b \cf5 init
\f0\b0 \cf4 ?(modelFileInfo: \cf9 FileInfo\cf4 , threadCount: \cf7 Int\cf4  = \cf11 1\cf4 ) \{\
    
\f1\b \cf5 let
\f0\b0 \cf4  modelFilename = modelFileInfo.name\
    
\f1\b \cf5 guard
\f0\b0 \cf4  
\f1\b \cf5 let
\f0\b0 \cf4  modelPath = \cf7 Bundle\cf4 .\cf12 main\cf4 .\cf12 path\cf4 (\
      forResource: modelFilename,\
      ofType: modelFileInfo.extension\
      ) 
\f1\b \cf5 else
\f0\b0 \cf4  \{\
        \cf12 print\cf4 (\cf10 "Failed to load the model file with name: \cf4 \\(modelFilename)\cf10 ."\cf4 )\
        
\f1\b \cf5 return
\f0\b0 \cf4  
\f1\b \cf5 nil
\f0\b0 \cf4 \
    \}\
    
\f1\b \cf5 do
\f0\b0 \cf4  \{\
      \cf13 interpreter\cf4  = 
\f1\b \cf5 try
\f0\b0 \cf4  \cf9 Interpreter\cf4 (modelPath: modelPath)\
    \} 
\f1\b \cf5 catch
\f0\b0 \cf4  
\f1\b \cf5 let
\f0\b0 \cf4  error \{\
      \cf12 print\cf4 (\cf10 "Failed to create the interpreter with error: \cf4 \\(error.\cf12 localizedDescription\cf4 )\cf10 "\cf4 )\
      
\f1\b \cf5 return
\f0\b0 \cf4  
\f1\b \cf5 nil
\f0\b0 \cf4 \
    \}\
  \}\
  \
\
  
\f1\b \cf5 func
\f0\b0 \cf4  \cf8 runModel\cf4 (withInput input: \cf7 Float\cf4 ) -> \cf7 Float\cf4 ? \{\
    
\f1\b \cf5 do
\f0\b0 \cf4  \{\
      
\f1\b \cf5 try
\f0\b0 \cf4  \cf13 interpreter\cf4 .\cf13 allocateTensors\cf4 ()\
      
\f1\b \cf5 var
\f0\b0 \cf4  data: \cf7 Float\cf4  = input\
      
\f1\b \cf5 let
\f0\b0 \cf4  buffer: \cf7 UnsafeMutableBufferPointer\cf4 <\cf7 Float\cf4 > = \cf7 UnsafeMutableBufferPointer\cf4 (start: &data, count: \cf11 1\cf4 )\
      
\f1\b \cf5 try
\f0\b0 \cf4  \cf13 interpreter\cf4 .\cf13 copy\cf4 (\cf7 Data\cf4 (buffer: buffer), toInputAt: \cf11 0\cf4 )\
      
\f1\b \cf5 try
\f0\b0 \cf4  \cf13 interpreter\cf4 .\cf13 invoke\cf4 ()\
      
\f1\b \cf5 let
\f0\b0 \cf4  outputTensor = 
\f1\b \cf5 try
\f0\b0 \cf4  \cf13 interpreter\cf4 .\cf13 output\cf4 (at: \cf11 0\cf4 )\
      
\f1\b \cf5 let
\f0\b0 \cf4  results: [\cf7 Float32\cf4 ] = [\cf7 Float32\cf4 ](unsafeData: outputTensor.\cf13 data\cf4 ) ?? []\
      
\f1\b \cf5 guard
\f0\b0 \cf4  
\f1\b \cf5 let
\f0\b0 \cf4  result = results.\cf12 first\cf4  
\f1\b \cf5 else
\f0\b0 \cf4  \{\
        
\f1\b \cf5 return
\f0\b0 \cf4  
\f1\b \cf5 nil
\f0\b0 \cf4 \
      \}\
      
\f1\b \cf5 return
\f0\b0 \cf4  result\
    \}\
    
\f1\b \cf5 catch
\f0\b0 \cf4  \{\
      \cf12 print\cf4 (error)\
      
\f1\b \cf5 return
\f0\b0 \cf4  
\f1\b \cf5 nil
\f0\b0 \cf4 \
    \}\
  \}\
\}\
\

\f1\b \cf5 extension
\f0\b0 \cf4  \cf7 Array\cf4  \{\
  
\f1\b \cf5 init
\f0\b0 \cf4 ?(unsafeData: \cf7 Data\cf4 ) \{\
    
\f1\b \cf5 guard
\f0\b0 \cf4  unsafeData.\cf12 count\cf4  \cf12 %\cf4  \cf7 MemoryLayout\cf4 <\cf9 Element\cf4 >.\cf12 stride\cf4  \cf12 ==\cf4  \cf11 0\cf4  
\f1\b \cf5 else
\f0\b0 \cf4  \{ 
\f1\b \cf5 return
\f0\b0 \cf4  
\f1\b \cf5 nil
\f0\b0 \cf4  \}\
    \cf14 #if\cf4  \cf14 swift\cf4 (>=\cf11 5.0\cf4 )\
    
\f1\b \cf5 self
\f0\b0 \cf4  = unsafeData.\cf12 withUnsafeBytes\cf4  \{ .\cf7 init\cf4 ($0.\cf12 bindMemory\cf4 (to: \cf9 Element\cf4 .
\f1\b \cf5 self
\f0\b0 \cf4 )) \}\
    \cf14 #else\cf4 \
    
\f1\b \cf5 self
\f0\b0 \cf4  = unsafeData.withUnsafeBytes \{\
      .init(UnsafeBufferPointer<\cf7 Element\cf4 >(\
        start: $0,\
        count: unsafeData.count / MemoryLayout<\cf7 Element\cf4 >.stride\
      ))\
    \}\
    \cf14 #endif\cf4   \cf2 // swift(>=5.0)\cf4 \
  \}\
\}\
}